export default function(){
	function MyPromise(executor){
		this.state='pending';
		this.result=undefined;
		this.queue=[];
		var doQueue=function(){
			var queue=this.queue;
			for(var i=0;i<queue.length;++i){
				queue[i](this);
			}
		}.bind(this);
		var resolve=function(value){
			if(this.state==='pending'){
				if(value&&value.then){
					try{
						value.then(resolve,reject);
					}catch(e){
						reject(e);
					}
				}else{
					this.state='fulfilled';
					this.result=value;
					doQueue();
				}
			}
		}.bind(this);
		var reject=function(reason){
			if(this.state==='pending'){
				this.state='rejected';
				this.result=reason;
				doQueue();
			}
		}.bind(this);
		try{
			executor(resolve,reject);
		}catch(e){
			reject(e);
		}
	}
	MyPromise.prototype=Object.create(null,{
		then:{
			value:function(onFulfilled,onRejected){
				if(this.state==='pending'){
					return new MyPromise(function(resolve,reject){
						this.queue.push(function(p){
							try{
								var call=p.state==='fulfilled'?onFulfilled:onRejected;
								if(call){
									resolve(call(p.result));
								}else{
									resolve(p);
								}
							}catch(e){
								reject(e);
							}
						});
					}.bind(this));
				}else{
					return new MyPromise(function(resolve){
						var call=this.state==='fulfilled'?onFulfilled:onRejected;
						if(call){
							resolve(call(this.result));
						}else{
							resolve(this);
						}
					}.bind(this));
				}
			},
		},
		catch:{
			value:function(onRejected){
				return this.then(undefined,onRejected);
			},
		},
		finally:{
			value:function(onFinally){
				return this.then(function(result){
					onFinally();
					return result;
				},function(result){
					onFinally();
					throw result;
				});
			},
		},
	});
	return MyPromise;
};
